//
//  UIDlgBuild.m
//  FyUILib
//
//  Created by luoc on 16/2/6.
//  Copyright © 2016年 luoc. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "UIDlgBuild.h"
#import "UIMarkup.h"
#import <UIKit/UIKit.h>
#import "UIControl.h"
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <assert.h>
#define ASSERT  aseert
const char* CharNext(const char* pstr)
{
    return ++pstr;
}

long _tcstoul(const char* pstr, char** pVar, int len)
{
    return strtol(pstr, pVar, len);
}

long _tcstol(const char* pstr, char** pVar, int len)
{
    return strtol(pstr, pVar, len);
}

@interface UIDlgBuild()
{
    CreateViewBlock _pCreateBlcok;
    CMarkup*        _pXml;
}
@end
@implementation UIDlgBuild
-(void)dealloc
{
}

- (UIView*)Create:(const char*)xml :(CreateViewBlock)pCallback :(UIManager*)pManager :(UIView*)pParent
{
    assert(xml != NULL && pManager != nil);
    _pCreateBlcok = pCallback;
    if ((*xml) =='<') {
        if (_pXml == NULL) {
            _pXml = [[CMarkup alloc] init];
        }
        if( ![_pXml Load:xml] ) return NULL;
    }else{
        if (_pXml == NULL) {
            _pXml = [[CMarkup alloc] init];
        }
        if( ![_pXml LoadFromeFile:xml] ) return NULL;
    }
    return [self Create:pCallback :pManager :pParent];
}

- (UIView*)Create:(CreateViewBlock)pCallback :(UIManager *)pManager :(UIView *)pParent
{

    _pCreateBlcok = pCallback;
    CMarkupNode* root = [_pXml GetRoot];
    if( ![root IsValid] ) return NULL;
#if 0   
    if( pManager ) {
        const char* pstrClass = NULL;
        int nAttributes = 0;
        const char* pstrName = NULL;
        const char* pstrValue = NULL;
        const char* pstr = NULL;
        
        pstrClass = [root GetName];
        if( strcmp(pstrClass, "Window") == 0 ) {
            if( pManager->GetPaintWindow() ) {
                int nAttributes = [root GetAttributeCount];
                for( int i = 0; i < nAttributes; i++ ) {
                    pstrName = [root GetAttributeName:i];
                    pstrValue = [root GetAttributeValueWithIndex:i];
                    if( strcmp(pstrName, "language") == 0 ) {
                        char* pstr = NULL;
                        int cx = _tcstol(pstrValue, &pstr, 10);  ASSERT(pstr);
                        int cy = _tcstol(pstr + 1, &pstr, 10);    ASSERT(pstr);
                        pManager->SetInitSize(cx, cy);
                    }
                    
                }
            }
        }
    }
#endif
    return [self _Parse:root :pParent :pManager];
}

-(UIView*)_Parse:(CMarkupNode*)pRoot :(UIView*)pParent :(UIManager*)pManager
{
    UIView* pReturn = NULL;
    for( CMarkupNode* node = [pRoot GetChild] ; [node IsValid]; node = [node GetSibling] ) {
        const char* pstrClass = [node GetName];
        if( strcmp(pstrClass, "Image") == 0 || strcmp(pstrClass, "Font") == 0 \
           || strcmp(pstrClass, "Default") == 0 || strcmp(pstrClass, "javascript") == 0 ) continue;
        
        UIView* pControl = NULL;
        if( strcmp(pstrClass, "Include") == 0 ) {
            if( [node HasAttributes] ) continue;
            long count = 1;
            char* pstr = NULL;
            char szValue[500] = { 0 };
            int cchLen = (int)strlen(szValue) - 1;
            if ( [node GetAttributeValueWithName:"count" :szValue :cchLen] )
                count = _tcstol(szValue, &pstr, 10);
            cchLen = (int)strlen(szValue) - 1;
            if ( [node GetAttributeValueWithName:"source" :szValue :cchLen] ) continue;
            continue;
        }
        else {
            int cchLen = (int)strlen(pstrClass);
            switch( cchLen ) {
                case 3:
                    if( strcmp(pstrClass, "Gif") == 0 )
                        pControl = [[CGifUI alloc] initWithUIManager:pManager];
                    break;
                case 4:
                    if( strcmp(pstrClass, "Edit") == 0 )                   pControl = [[CEditUI alloc] initWithUIManager:pManager];
                    else if( strcmp(pstrClass, "List") == 0 )              pControl = [[CListUI alloc] initWithUIManager:pManager];
                    else if( strcmp(pstrClass, "Text") == 0 )              pControl = [[CTextUI alloc] initWithUIManager:pManager];
                    break;
                case 5:
                    if( strcmp(pstrClass, "Combo") == 0 )                  pControl = [[CComboUI alloc] initWithUIManager:pManager];
                    else if( strcmp(pstrClass, "Label") == 0 )             pControl = [[CLabelUI alloc] initWithUIManager:pManager];
                    else if( strcmp(pstrClass, "List2") == 0 )              pControl = [[CListUI2 alloc] initWithUIManager:pManager];
                    break;
                case 6:
                    if( strcmp(pstrClass, "Button") == 0 )                 pControl = [[CButtonUI alloc] initWithUIManager:pManager];
                    else if( strcmp(pstrClass, "Option") == 0 )            pControl = [[COptionUI alloc] initWithUIManager:pManager];
                    else if( strcmp(pstrClass, "Switch") == 0)              pControl = [[CSwitchUI alloc] initWithUIManager:pManager];
                    else if( strcmp(pstrClass, "Slider") == 0 )            pControl = [[CSliderUI alloc] initWithUIManager:pManager];
                    else if ( strcmp(pstrClass, "CNumUI") == 0 )			pControl = [[CNumberUI alloc] initWithUIManager:pManager];
                    break;
                case 7:
                    if( strcmp(pstrClass, "Control") == 0 )                pControl = [[CControlUI alloc] initWithUIManager:pManager];
                    else if (strcmp(pstrClass, "CTimeUI") == 0)			pControl = [[CTimeUI alloc] initWithUIManager:pManager];
                    break;
                case 8:
                    if( strcmp(pstrClass, "Progress") == 0 )               pControl = [[CProgressUI alloc] initWithUIManager:pManager];
                    else if(  strcmp(pstrClass, "RichEdit") == 0 )         pControl = [[CRichEditUI alloc] initWithUIManager:pManager];
                    else if (strcmp(pstrClass, "DateTime") == 0)			pControl = [[CDateUI alloc] initWithUIManager:pManager];
                    else if (strcmp(pstrClass, "MBSlider") == 0)			pControl = [[CMBSliderUI alloc] initWithUIManager:pManager];
                    break;
                case 9:
                    if( strcmp(pstrClass, "Container") == 0 )              pControl = [[CContainerUI alloc] initWithUIManager:pManager];
                    else if( strcmp(pstrClass, "TabLayout") == 0 )
                        pControl = [[CTabLayoutUI alloc] initWithUIManager:pManager];
                    else if ( strcmp(pstrClass, "ImageView") == 0)
                        pControl = [[CImageUI alloc] initWithUIManager:pManager];
                    break;
                case 10:
                    if( strcmp(pstrClass, "LayoutView") == 0 )  pControl = [[CLayoutUI alloc] initWithUIManager:pManager];
                    else if( strcmp(pstrClass, "ScrollView") == 0 )  pControl = [[CScrollViewUI alloc] initWithUIManager:pManager];
                    
                    break;
                case 11:
                    if( strcmp(pstrClass, "ListElement") == 0 )         pControl = [[CListElementUI alloc] initWithUIManager:pManager];
                    break;
                case 12:
                    if( strcmp(pstrClass, "ListElementf") == 0 )         pControl = [[CListElementUI alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:[NSString stringWithFormat:@"cell_%p", pParent] :pManager];
                    break;
                case 20:
                    break;
            }
            if( pControl == NULL && _pCreateBlcok != NULL ) {
                pControl = _pCreateBlcok(pstrClass);
            }
        }
        
        if( pControl == NULL ) {
            if (strcmp(pstrClass, "JSScript") == 0){
                [pManager initJs];
                if( [node HasAttributes] ) {
                    int nAttributes = [node GetAttributeCount];
                    for( int i = 0; i < nAttributes; i++ ) {
                        if (strcmp([node GetAttributeName:i], "src") == 0) {
                            [pManager addJsFile:[node GetAttributeValueWithIndex:i]];
                        }
                    }
                }
            }else if(strcmp(pstrClass, "ListSection") == 0){
                assert([NSStringFromClass([pParent class]) isEqualToString:@"CListUI"]);
                CListUI* pList = (CListUI*)pParent;
                [pList addSection];
                [self _Parse:node :pParent :pManager];
                int nAttributes = [node GetAttributeCount];
                for( int i = 0; i < nAttributes; i++ ) {
                    [pList SetAttribute:[node GetAttributeName:i] :[node GetAttributeValueWithIndex:i] ];
                }
            }
            continue;
        }
        
        // Add children
        if( [node HasChildren] ) {
            [self _Parse:node :pControl :pManager];
        }
        
        if( pParent != NULL ) {
            if (strcmp(pstrClass, "ListElement") == 0 || strcmp(pstrClass, "ListElementf") == 0) {
                assert([NSStringFromClass([pParent class]) isEqualToString:@"CListUI"] || [NSStringFromClass([pParent class]) isEqualToString:@"CListUI2"]);
                id<UIListAttribute> o = (id<UIListAttribute>)pParent;
                [o AddListElement:(CListElementUI*)pControl];
            }else{
                if ([NSStringFromClass([pParent class]) isEqualToString:@"CTabLayoutUI"]) {
                    id<UITabAttribute> o = (id<UITabAttribute>)pParent;
                    [o AddTabElement:pControl];
                }
                [pParent addSubview:pControl];
            }
        }
        
#if 0
        if( pManager ) {
            pControl->SetManager(pManager, NULL, false);
            const char* pDefaultAttributes = pManager->GetDefaultAttributeList(pstrClass);
            if( pDefaultAttributes ) {
                pControl->ApplyAttributeList(pDefaultAttributes);
            }
        }
#endif
        
        // Process attributes
        if( [node HasAttributes] ) {
            // Set ordinary attributes
            int nAttributes = [node GetAttributeCount];
            id<UIAttribute> pTempUI = (id<UIAttribute>)pControl;
            for( int i = 0; i < nAttributes; i++ ) {
                [pTempUI SetAttribute:[node GetAttributeName:i] :[node GetAttributeValueWithIndex:i] ];
            }
        }
#if 0
        if( pManager ) {
            pControl->SetManager(NULL, NULL, false);
        }
#endif
        
        // Return first item
        if( pReturn == NULL ) pReturn = pControl;
    }
    return pReturn;
}

@end